/*
 * PngPlus.cpp
 *
 *  Created on: Feb 4, 2013
 *      Author: baneling
 */

#include "PngPlus.h"

using namespace png;

PngPlus::PngPlus(string filename,bool rgb,int height,int width,bool init,bool verbose)
{
	this->rgbImage=rgb;
	this->verbose=verbose;
	cout<<"PngPlus verbose is: "<<this->verbose<<endl;
	this->filename=filename;
	this->height=height+IMAGERATIO;
	this->width=width+IMAGERATIO;

	if(init)
	{
		cout<<"Creating new image: "<<this->filename<<endl;
		if(this->rgbImage)
		{
			//image<rgb_pixel> imm(this->width,this->height);
			image<rgba_pixel> imm(this->width,this->height);
			this->rgba=imm;
		}
		else
		{
			image<gray_pixel> imm(this->width,this->height);
			this->gray=imm;
		}
		this->init();
	}
	else
	{
		cout<<"Reading image from file: "<<this->filename<<endl;
		if(this->rgbImage)
		{
			//image<rgb_pixel> imm(this->filename);
			image<rgba_pixel> imm(this->filename);
			this->rgba=imm;
		}
		else
		{
			image<gray_pixel> imm(this->filename);
			this->gray=imm;
		}
	}
}

PngPlus::~PngPlus() {
	// TODO Auto-generated destructor stub
}

void PngPlus::init()
{
	if(this->verbose)
	{
		if(this->rgbImage)
			cout<<"Initializing RGB image: "<<this->filename<<endl;
		else
			cout<<"Initializing GRAY image: "<<this->filename<<endl;
	}

	for (size_t y = 0; y < this->height; ++y)
	{
		for (size_t x = 0; x < this->width; ++x)
		{
			if(this->rgbImage)
				this->rgba[y][x]=rgba_pixel(BLACK,BLACK,BLACK,TRASPARENCY);
				//this->rgb[y][x]=rgb_pixel(BLACK,BLACK,BLACK);
			else
				this->gray[y][x]=gray_pixel(BLACK);
		}
	}
	if(this->rgbImage)
	{
		this->setPixel(0,WMAX,1,0);
		this->setPixel(HMAX,0,1,90);
		this->setPixel(0,-WMAX,1,180);
		this->setPixel(-HMAX,0,1,270);
	}
	this->save();
}

void PngPlus::save()
{
	if(this->verbose)
		cout<<"saving image: "<<this->filename<<endl;
	if(this->rgbImage)
		this->rgba.write(this->filename);
	else
		this->gray.write(this->filename);
}

void PngPlus::setPixel(int  hY,int wX,double value)
{
	size_t y,x;
	y=(HMAX-hY)*IMAGERATIO;
	x=(wX+WMAX)*IMAGERATIO;

	value=((value+1)/2)*255;
	//cout<<"hy: "<<hY<<" wx: "<<wX<<" y: "<<y<<" x: "<<x<<endl;
	if(this->verbose)
		cout<<"Changing pixel: ("<<hY<<","<<wX<<") with gray value: "<<(int)value<<endl;
	this->changePixel(y,x,(int)value);
	this->save();
}

void PngPlus::setPixel(int  hY,int wX,double value,int direction)
{
	size_t y,x;
	y=(HMAX-hY)*IMAGERATIO;
	x=(wX+WMAX)*IMAGERATIO;

	value=((value+1)/2)*255;
	//cout<<"hy: "<<hY<<" wx: "<<wX<<" y: "<<y<<" x: "<<x<<endl;
	if(this->verbose)
		cout<<"Changing pixel: ("<<hY<<","<<wX<<") in direction: "<<direction<<" with value: "<<(int)value<<endl;
	this->changePixel(y,x,this->getPixelValueAlpha(direction,(size_t)value));//todo change in base al tipo di immagine
	this->save();
}

rgba_pixel PngPlus::getPixelValueAlpha(int direction,size_t intensity)
{
	rgba_pixel pixel;

	switch(direction)
	{
	case 0:		//white
		pixel=rgba_pixel(intensity,intensity,intensity);
		break;
	case 90:	//red
		pixel=rgba_pixel(intensity,0,0);
		break;
	case 180:	//green
		pixel=rgba_pixel(0,intensity,0);
		break;
	case 270:	//blue
		pixel=rgba_pixel(0,0,intensity);
		break;
	default:
		cout<<"ERROR: not valid direction in getPixelValue: "<<direction<<endl;
		break;
	}

	return pixel;
}
rgb_pixel PngPlus::getPixelValue(int direction,size_t intensity)
{
	rgb_pixel pixel;

	switch(direction)
	{
	case 0:		//white
		pixel=rgb_pixel(intensity,intensity,intensity);
		break;
	case 90:	//red
		pixel=rgb_pixel(intensity,0,0);
		break;
	case 180:	//green
		pixel=rgb_pixel(0,intensity,0);
		break;
	case 270:	//blue
		pixel=rgb_pixel(0,0,intensity);
		break;
	default:
		cout<<"ERROR: not valid direction in getPixelValue: "<<direction<<endl;
		break;
	}

	return pixel;
}

void PngPlus::changePixel(size_t hY,size_t wX,rgba_pixel pixel)//rgba image
{
	for(size_t y=hY;y<hY+IMAGERATIO;++y)
	{
		for(size_t x=wX;x<wX+IMAGERATIO;++x)
		{
			this->rgba[y][x] = pixel;
		}
	}
}
/*
void PngPlus::changePixel(size_t hY,size_t wX,rgb_pixel pixel)//rgb image
{
	for(size_t y=hY;y<hY+IMAGERATIO;++y)
	{
		for(size_t x=wX;x<wX+IMAGERATIO;++x)
		{
			this->rgb[y][x] = pixel;
		}
	}
}
*/
void PngPlus::changePixel(size_t hY,size_t wX,int value)//gray image
{
	for(size_t y=hY;y<hY+IMAGERATIO;++y)
	{
		for(size_t x=wX;x<wX+IMAGERATIO;++x)
		{
			this->gray[y][x] = gray_pixel(value);
		}
	}
}
